#include "utils.h"


bool setIntParam(ParamSet &p, const FnKat::GroupAttribute &groupAttr,
                 const string &attrName, const string &paramName,
                 int nItems, float time)
{
    FnKat::IntAttribute attr = groupAttr.getChildByName(attrName);
    if(attr.isValid())
    {
        FnKat::IntConstVector vec = attr.getNearestSample(time);
        nItems = (nItems < 0)? vec.size(): nItems;
        string name = (paramName == "")? attrName: paramName;
        p.AddInt(name, vec.data(), nItems);
        return true;
    }

    return false;
}

bool setBoolParam(ParamSet &p, const FnKat::GroupAttribute &groupAttr,
                  const string &attrName, const string &paramName,
                  int nItems, float time)
{
    FnKat::Attribute attr = groupAttr.getChildByName(attrName);
    FnKat::IntAttribute intAttr = attr;
    FnKat::StringAttribute strAttr = attr;
    bool *bValues = NULL;

    if(intAttr.isValid())
    {
        FnKat::IntConstVector vec = intAttr.getNearestSample(time);
        FnKat::IntConstVector::const_iterator iIt = vec.begin();
        nItems = (nItems < 0)? vec.size(): nItems;
        bValues = new bool[nItems];

        bool *bIt = bValues;
        for(; iIt != vec.end(); ++iIt, ++bIt)
        {
            *bIt = (bool)*iIt;
        }

    }
    else if(strAttr.isValid())
    {
        FnKat::StringConstVector vec = strAttr.getNearestSample(time);
        FnKat::StringConstVector::const_iterator sIt = vec.begin();
        nItems = (nItems < 0)? vec.size(): nItems;
        bValues = new bool[nItems];

        bool *bIt = bValues;
        for(; sIt != vec.end(); ++sIt, ++bIt)
        {
            *bIt = (*sIt == "yes");
        }
    }

    if(bValues != NULL)
    {
        string name = (paramName == "")? attrName: paramName;
        p.AddBool(name, bValues, nItems);
        delete[] bValues;
        return true;
    }

    return false;
}


bool setFloatParam(ParamSet &p, const FnKat::GroupAttribute &groupAttr,
                   const string &attrName, const string &paramName,
                   int nItems, float time)
{
    FnKat::FloatAttribute attr = groupAttr.getChildByName(attrName);
    if(attr.isValid())
    {
        FnKat::FloatConstVector vec = attr.getNearestSample(time);
        nItems = (nItems < 0)? vec.size(): nItems;
        string name = (paramName == "")? attrName: paramName;
        p.AddFloat(name, vec.data(), nItems);
        return true;
    }

    return false;
}


bool setDoubleParam(ParamSet &p, const FnKat::GroupAttribute &groupAttr,
                    const string &attrName, const string &paramName,
                    int nItems, float time)
{
    FnKat::DoubleAttribute attr = groupAttr.getChildByName(attrName);
    if(attr.isValid())
    {
        //There is no AddDouble in ParamSet, so we need to convert all the
        //doubles into floats
        FnKat::DoubleConstVector vec = attr.getNearestSample(time);
        FnKat::DoubleConstVector::const_iterator dIt = vec.begin();
        nItems = (nItems < 0)? vec.size(): nItems;
        float *fValues = new float[nItems];

        float *fIt = fValues;
        for(; dIt != vec.end(); ++dIt, ++fIt)
        {
            *fIt = (float)*dIt;
        }

        string name = (paramName == "")? attrName: paramName;
        p.AddFloat(name, fValues, nItems);
        delete[] fValues;
        return true;
    }

    return false;
}


bool setStringParam(ParamSet &p, const FnKat::GroupAttribute &groupAttr,
                    const string &attrName, const string &paramName,
                    int nItems, float time)
{
    FnKat::StringAttribute attr = groupAttr.getChildByName(attrName);
    if(attr.isValid())
    {
        FnKat::StringConstVector vec = attr.getNearestSample(time);
        nItems = (nItems < 0)? vec.size(): nItems;
        string name = (paramName == "")? attrName: paramName;
        p.AddString(name, vec.data(), nItems);
        return true;
    }

    return false;
}

void error(std::string message)
{
    std::cerr << "PBRT Error: " << message << std::endl;
}
